from django.test import TestCase
from django.conf import settings
import StringIO
from minixsv import pyxsval

from models import ObjectType, Field, ValidValue, \
    Party, Resource, Contact, Property, Protocol, Visualiser, \
    InputParameter, ParameterGroup, ClusterFinder, SubvolumeExtractor, \
    CompositeProtocol, ChildProtocol, ParameterGroupMember, Simulator, \
    Physics, Visualisation, Simulation, Snapshot, ObjectCollection, \
    TargetObjectType, TargetProcess, RepresentationObjectType, \
    ExperimentRepresentationObject, AppliedPhysics, PropertyGroup, \
    PropertyGroupMember, WebService, InputDataset, ClusterDetection, \
    NumericParameterSetting, GenericParameterSetting, SubvolumeExtraction, \
    Algorithm, CompositeExperiment, ChildExperiment, ChildObject, \
    Characterisation, Project, ProjectExperiment, ExperimentProperty

class FieldTestCase(TestCase):
    def setUp(self):
        self.field = Field.objects.create(name='RadiationFieldType',
                                          datatype='int',
                                          cardinality='0..1')

    def testInit(self):
        self.assertEquals(self.field.datatype, 'int')
        self.assertEquals(self.field.cardinality, '0..1')

    def testToXML(self):
        x = self.field.to_xml()
        self.assertNotEquals(x.find('<cardinality>0..1</cardinality>'), -1)
        self.assertNotEquals(x.find('id="'), -1)

    def testToXMLWithValues(self):
        v1 = ValidValue(value='0', description='', label='None')
        v2 = ValidValue(value='1', label='Haardt-Madau 2001')
        self.field.validvalue_set.add(v1)
        self.field.validvalue_set.add(v2)
        x = self.field.to_xml()
        self.assertNotEquals(x.find('<cardinality>0..1</cardinality>'), -1)
        self.assertNotEquals(x.find('<validValue'), -1)
        self.assertNotEquals(x.find('<value>1</value>'), -1)

class PartyTestCase(TestCase):
    def setUp(self):
        self.party = Party.objects.create(name='Emma Frost',
                                          address='New York, NY')

    def testInit(self):
        self.assertNotEquals(self.party.name, 'Shinobi Shaw')
        self.assertNotEquals(self.party.address, 'Hong Kong')

    def testToXML(self):
        x = self.party.to_xml()
        self.assertNotEquals(x.find('<simdb:aParty'), -1)
        self.assertNotEquals(x.find('</simdb:aParty>'), -1)
        self.assertNotEquals(x.find('<name>Emma Frost</name>'), -1)

    def testValidXML(self):
        x = self.party.to_xml()
        gen_wrapper = pyxsval.parseAndValidateXmlInputString(x)
        self.assertNotEquals(gen_wrapper, None)  

class ResourceTestCase(TestCase):
    def setUp(self):
        self.resource = Resource.objects.create(name='Inner Circle',
                                                maincontact = 
                                                Party.objects.create(name='Roberto da Costa',
                                                                     address='Brazil'))
    def testAddContact(self):
        sunspot = Party.objects.create(name='Roberto da Costa',
                                       address='Brazil')

        c = Contact.objects.create(role='owner', party=sunspot,
                                   resource=self.resource)

        self.assertEquals(self.resource.id, c.resource.id)

    def testToXML(self):
        x = self.resource.to_xml()
        self.assertNotEquals(x.find('<name>Inner Circle</name>'), -1)
        self.assertNotEquals(x.find('%s#Resource/' % (settings.SIMDB_IVO_ROOT)), -1)

    def testToXMLWithContacts(self):
        p = Party.objects.create(name='Emma Frost',
                                 address='New York, NY')
        c = Contact.objects.create(role='owner', party=p,
                                   resource=self.resource)
        x = self.resource.to_xml()
        self.assertNotEquals(x.find('<contact'), -1)
        self.assertNotEquals(x.find('<party'), -1)
        self.assertNotEquals(x.find('<role>owner</role>'), -1)

class PropertyTestCase(TestCase):
    def setUp(self):
        ot = ObjectType.objects.create(name='star')
        self.property = Property.objects.create(name='luminosity',
                                                datatype='float',
                                                cardinality='0..1', objecttype=ot)

    def testInit(self):
        self.assertEquals(self.property.datatype, 'float')
        self.assertEquals(self.property.cardinality, '0..1')

    def testToXML(self):
        x = self.property.to_xml()
        self.assertNotEquals(x.find('<name>luminosity</name>'), -1)


class ElementTestCase(TestCase):
    fixtures = ['simdb_models/fixtures/sim1.xml']

    def setUp(self):
        # The ids are pulled from the fixtures' XML file
        self.simdb_element = Simulation.objects.get(id=2)
        self.simdb_element_type = Simulation

    def testValidXML(self):
        # Test a single install
        x = self.simdb_element.to_xml()
        # print x
        # pyxsval will throw various errors if the xml isn't valid
        # so if we get to the assert, we've passed
        gen_wrapper = pyxsval.parseAndValidateXmlInputString(x)
        self.assertNotEquals(gen_wrapper, None)

    def testValidXMLAll(self):
        # Test all the instances in the database for validity
        objects = self.simdb_element_type.objects.all()
        for obj in objects:
            x = self.simdb_element.to_xml()
            gen_wrapper = pyxsval.parseAndValidateXmlInputString(x)
            self.assertNotEquals(gen_wrapper, None)

class VisualiserTestCase(ElementTestCase):
    fixtures = ['simdb_models/fixtures/sim1.xml']
    def setUp(self):
        self.simdb_element = Visualiser.objects.get(id=3)
        self.simdb_element_type = Visualiser

class ClusterFinderTestCase(ElementTestCase):
    fixtures = ['simdb_models/fixtures/sim1.xml']
    def setUp(self):
        self.simdb_element = ClusterFinder.objects.get(id=8)
        self.simdb_element_type = ClusterFinder

class SubvolumeExtractorTestCase(ElementTestCase):
    fixtures = ['simdb_models/fixtures/sim1.xml']
    def setUp(self):
        self.simdb_element = SubvolumeExtractor.objects.get(id=6)
        self.simdb_element_type = SubvolumeExtractor

class CompositeProtocolTestCase(ElementTestCase):
    fixtures = ['simdb_models/fixtures/sim1.xml']
    def setUp(self):
        self.simdb_element = CompositeProtocol.objects.get(id=5)
        self.simdb_element_type = CompositeProtocol

class SimulatorTestCase(ElementTestCase):
    fixtures = ['simdb_models/fixtures/sim1.xml']
    def setUp(self):
        self.simdb_element = Simulator.objects.get(id=1)
        self.simdb_element_type = Simulator

class ClusterDetectionTestCase(ElementTestCase):
    fixtures = ['simdb_models/fixtures/sim1.xml']
    def setUp(self):
        self.simdb_element = ClusterDetection.objects.get(id=9)
        self.simdb_element_type = ClusterDetection

class SubvolumeExtractionTestCase(ElementTestCase):
    fixtures = ['simdb_models/fixtures/sim1.xml']
    def setUp(self):
        self.simdb_element = SubvolumeExtraction.objects.get(id=11)
        self.simdb_element_type = SubvolumeExtraction

class VisualisationTestCase(ElementTestCase):
    fixtures = ['simdb_models/fixtures/sim1.xml']
    def setUp(self):
        self.simdb_element = Visualisation.objects.get(id=10)
        self.simdb_element_type = Visualisation

class CompositeExperimentTestCase(ElementTestCase):
    fixtures = ['simdb_models/fixtures/sim1.xml']
    def setUp(self):
        self.simdb_element = CompositeExperiment.objects.get(id=12)
        self.simdb_element_type = CompositeExperiment

class ProjectTestCase(ElementTestCase):
    fixtures = ['simdb_models/fixtures/sim1.xml']
    def setUp(self):
        self.simdb_element = Project.objects.get(id=13)
        self.simdb_element_type = Project

class SimulationTestCase(TestCase):
    fixtures = ['simdb_models/fixtures/sim1.xml']

    def setUp(self):
        # The ids are pulled from the fixtures' XML file
        self.simdb_element = Simulation.objects.get(id=2)

    def testHasGeneric(self):
        # Test a single install
        x = self.simdb_element.to_xml()
        self.assertNotEquals(x.find('we gotta'), -1)
